<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据同步配置管理系统</title>
    <!-- Element UI 样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <!-- Element UI JS -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <!-- Axios -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <!-- ECharts -->
    <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.0/echarts.min.js"></script>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
    }

    :root {
        --primary-color: #409EFF;
        --success-color: #67C23A;
        --warning-color: #E6A23C;
        --danger-color: #F56C6C;
        --info-color: #909399;
        --bg-color: #f5f7fa;
        --text-color: #303133;
        --border-color: #e4e7ed;
        --sidebar-bg: #001529;
        --header-height: 60px;
        --sidebar-width: 200px;
        --stats-bg: #ffffff;
    }

    body {
        background-color: var(--bg-color);
        color: var(--text-color);
        height: 100vh;
        overflow: hidden;
    }

    .app-container {
        display: flex;
        height: 100vh;
    }

    /* 侧边栏样式 */
    .sidebar {
        width: var(--sidebar-width);
        background: var(--sidebar-bg);
        color: #fff;
        height: 100%;
        transition: width 0.3s;
        overflow: hidden;
        display: flex;
        flex-direction: column;
    }

    .logo-area {
        height: var(--header-height);
        display: flex;
        align-items: center;
        justify-content: center;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .logo-text {
        font-size: 18px;
        font-weight: bold;
        white-space: nowrap;
    }

    .menu-container {
        flex: 1;
        overflow-y: auto;
        padding: 10px 0;
    }

    .menu-item {
        padding: 14px 20px;
        cursor: pointer;
        transition: background-color 0.3s;
        display: flex;
        align-items: center;
    }

    .menu-item:hover {
        background-color: rgba(255, 255, 255, 0.1);
    }

    .menu-item.active {
        background-color: var(--primary-color);
    }

    .menu-icon {
        margin-right: 10px;
        font-size: 18px;
        min-width: 24px;
        text-align: center;
    }

    .menu-text {
        transition: opacity 0.3s;
        white-space: nowrap;
    }

    /* 主内容区样式 */
    .main-content {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .header {
        height: var(--header-height);
        background: #fff;
        box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
        display: flex;
        align-items: center;
        padding: 0 20px;
        justify-content: space-between;
        z-index: 10;
    }

    .toggle-btn {
        font-size: 20px;
        cursor: pointer;
        color: var(--text-color);
        padding: 5px;
    }

    .user-info {
        display: flex;
        align-items: center;
    }

    .user-name {
        margin-right: 10px;
    }

    .user-avatar {
        width: 36px;
        height: 36px;
        border-radius: 50%;
        background-color: var(--primary-color);
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: bold;
    }

    .content-area {
        flex: 1;
        padding: 20px;
        overflow: auto;
    }

    /* 卡片样式 */
    .card {
        background: #fff;
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
        padding: 20px;
        margin-bottom: 20px;
    }

    .card-title {
        font-size: 18px;
        font-weight: bold;
        margin-bottom: 20px;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }

    /* 表格样式 */
    .table-container {
        margin-top: 20px;
        overflow-x: auto;
    }

    .el-table {
        width: 100%;
        border-collapse: collapse;
        min-width: 1000px;
    }

    .el-table th {
        background-color: #f5f7fa;
        color: #606266;
        font-weight: bold;
        text-align: left;
        padding: 12px 10px;
        border-bottom: 1px solid var(--border-color);
    }

    .el-table td {
        padding: 12px 10px;
        border-bottom: 1px solid var(--border-color);
    }

    .el-table tr:hover {
        background-color: #f5f7fa;
    }

    .status-badge {
        display: inline-block;
        padding: 4px 8px;
        border-radius: 4px;
        font-size: 12px;
    }

    .status-enabled {
        background-color: #f0f9eb;
        color: var(--success-color);
    }

    .status-disabled {
        background-color: #fef0f0;
        color: var(--danger-color);
    }

    .priority-high {
        background-color: #fef0f0;
        color: var(--danger-color);
    }

    .priority-medium {
        background-color: #fdf6ec;
        color: var(--warning-color);
    }

    .priority-low {
        background-color: #f0f9eb;
        color: var(--success-color);
    }

    /* 按钮样式 */
    .btn {
        padding: 8px 15px;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;
        transition: all 0.3s;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .btn i {
        margin-right: 5px;
    }

    .btn-primary {
        background-color: var(--primary-color);
        color: white;
    }

    .btn-primary:hover {
        background-color: #66b1ff;
    }

    .btn-success {
        background-color: var(--success-color);
        color: white;
    }

    .btn-success:hover {
        background-color: #85ce61;
    }

    .btn-warning {
        background-color: var(--warning-color);
        color: white;
    }

    .btn-warning:hover {
        background-color: #ebb563;
    }

    .btn-danger {
        background-color: var(--danger-color);
        color: white;
    }

    .btn-danger:hover {
        background-color: #f78989;
    }

    .btn-info {
        background-color: var(--info-color);
        color: white;
    }

    .btn-info:hover {
        background-color: #a6a9ad;
    }

    .action-btn {
        padding: 6px 10px;
        font-size: 12px;
        margin-right: 5px;
    }

    /* 搜索区域 */
    .search-area {
        display: flex;
        flex-wrap: wrap;
        margin-bottom: 20px;
        gap: 15px;
        align-items: center;
        background: #f8fafc;
        padding: 16px;
        border-radius: 6px;
    }

    .search-item {
        display: flex;
        align-items: center;
    }

    .search-label {
        margin-right: 10px;
        width: 80px;
        text-align: right;
        white-space: nowrap;
    }

    .search-input {
        padding: 8px 12px;
        border: 1px solid var(--border-color);
        border-radius: 4px;
        width: 180px;
        transition: border-color 0.3s;
    }

    .search-input:focus {
        outline: none;
        border-color: var(--primary-color);
    }

    .search-select {
        padding: 8px 12px;
        border: 1px solid var(--border-color);
        border-radius: 4px;
        width: 180px;
        background-color: white;
    }

    /* 分页样式 */
    .pagination {
        display: flex;
        justify-content: center;
        margin-top: 20px;
        padding: 10px 0;
    }

    .pagination button {
        margin: 0 5px;
        padding: 6px 12px;
        border: 1px solid var(--border-color);
        border-radius: 4px;
        background: white;
        cursor: pointer;
        min-width: 32px;
    }

    .pagination button:hover:not([disabled]) {
        border-color: var(--primary-color);
        color: var(--primary-color);
    }

    .pagination button.active {
        background-color: var(--primary-color);
        color: white;
        border-color: var(--primary-color);
    }

    .pagination button[disabled] {
        cursor: not-allowed;
        opacity: 0.6;
    }

    /* 统计卡片 */
    .stats-cards {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
        margin-bottom: 30px;
    }

    .stats-card {
        flex: 1;
        min-width: 200px;
        background: var(--stats-bg);
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
        padding: 20px;
        display: flex;
        flex-direction: column;
        transition: all 0.3s ease;
        border-top: 4px solid transparent;
    }

    .stats-card:hover {
        transform: translateY(-5px);
        box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
    }

    .card-icon {
        font-size: 28px;
        margin-bottom: 15px;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgba(64, 158, 255, 0.1);
    }

    .card-value {
        font-size: 32px;
        font-weight: bold;
        margin: 5px 0;
        transition: all 0.5s ease;
    }

    .card-label {
        color: #909399;
        font-size: 14px;
        margin-top: 5px;
    }

    .stats-card-total {
        border-top-color: var(--primary-color);
    }

    .stats-card-total .card-icon {
        background: rgba(64, 158, 255, 0.1);
        color: var(--primary-color);
    }

    .stats-card-enabled {
        border-top-color: var(--success-color);
    }

    .stats-card-enabled .card-icon {
        background: rgba(103, 194, 58, 0.1);
        color: var(--success-color);
    }

    .stats-card-disabled {
        border-top-color: var(--danger-color);
    }

    .stats-card-disabled .card-icon {
        background: rgba(245, 108, 108, 0.1);
        color: var(--danger-color);
    }

    .stats-card-high {
        border-top-color: #F56C6C;
    }

    .stats-card-high .card-icon {
        background: rgba(245, 108, 108, 0.1);
        color: #F56C6C;
    }

    /* 图表区域 */
    .chart-container {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
    }

    .chart-card {
        flex: 1;
        min-width: 400px;
        height: 300px;
        background: white;
        border-radius: 4px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        padding: 15px;
    }

    .chart-title {
        font-size: 16px;
        margin-bottom: 15px;
        color: #606266;
        text-align: center;
        font-weight: bold;
    }

    .chart-content {
        height: calc(100% - 30px);
    }

    /* 表单样式 */
    .form-container {
        max-width: 800px;
        margin: 0 auto;
    }

    .form-row {
        display: flex;
        margin-bottom: 20px;
        flex-wrap: wrap;
    }

    .form-item {
        flex: 1;
        min-width: 300px;
        margin-right: 20px;
        margin-bottom: 10px;
    }

    .form-item:last-child {
        margin-right: 0;
    }

    .form-label {
        display: block;
        margin-bottom: 8px;
        font-weight: 500;
    }

    .form-label.required::after {
        content: " *";
        color: var(--danger-color);
    }

    .form-input {
        width: 100%;
        padding: 10px 12px;
        border: 1px solid var(--border-color);
        border-radius: 4px;
        transition: border-color 0.3s;
    }

    .form-input:focus {
        outline: none;
        border-color: var(--primary-color);
    }

    .form-select {
        width: 100%;
        padding: 10px 12px;
        border: 1px solid var(--border-color);
        border-radius: 4px;
        background-color: white;
    }

    .form-radio-group {
        display: flex;
        gap: 20px;
        margin-top: 5px;
    }

    .form-radio {
        display: flex;
        align-items: center;
    }

    .form-radio input {
        margin-right: 5px;
    }

    .form-actions {
        display: flex;
        justify-content: center;
        margin-top: 30px;
    }

    .submit-btn {
        padding: 10px 30px;
        background-color: var(--primary-color);
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 16px;
    }

    .cancel-btn {
        padding: 10px 30px;
        background-color: #909399;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 16px;
        margin-right: 15px;
    }

    /* 响应式调整 */
    @media (max-width: 992px) {
        .sidebar {
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            z-index: 100;
            transform: translateX(-100%);
            transition: transform 0.3s;
        }

        .sidebar.open {
            transform: translateX(0);
        }

        .overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            z-index: 99;
        }

        .sidebar.open + .overlay {
            display: block;
        }

        .chart-card {
            min-width: 100%;
        }

        .stats-card {
            min-width: calc(50% - 20px);
        }
    }

    .notification {
        position: fixed;
        top: 20px;
        right: 20px;
        padding: 15px 25px;
        background: #fff;
        border-radius: 4px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        z-index: 2000;
        display: flex;
        align-items: center;
        transition: all 0.3s;
    }

    .notification.success {
        border-left: 4px solid #67c23a;
    }

    .notification.error {
        border-left: 4px solid #f56c6c;
    }

    .notification.warning {
        border-left: 4px solid #e6a23c;
    }

    .notification-content {
        margin-left: 10px;
    }

    .notification-title {
        font-weight: bold;
        font-size: 16px;
    }

    .notification-message {
        margin-top: 5px;
        font-size: 14px;
    }

    /* PC 端侧边栏收起状态 */
    @media (min-width: 993px) {
        .sidebar.collapsed {
            width: 64px;
        }

        .sidebar.collapsed .logo-text,
        .sidebar.collapsed .menu-text {
            opacity: 0;
            width: 0;
            overflow: hidden;
            display: none;
        }

        .sidebar.collapsed .menu-item {
            justify-content: center;
            padding: 14px 0;
        }

        .sidebar.collapsed .menu-icon {
            margin-right: 0;
            font-size: 20px;
        }

        .sidebar.collapsed + .main-content {
            margin-left: 64px;
        }
    }

    /* 确保主内容区有过渡效果 */
    .main-content {
        transition: margin-left 0.3s;
    }

    /* 全局统计标题 */
    .global-stats-title {
        font-size: 18px;
        font-weight: 600;
        margin-bottom: 15px;
        color: #303133;
        display: flex;
        align-items: center;
    }

    .global-stats-title::before {
        content: "";
        display: inline-block;
        width: 4px;
        height: 18px;
        background: var(--primary-color);
        margin-right: 10px;
        border-radius: 2px;
    }

    .stats-description {
        font-size: 13px;
        color: #909399;
        margin-top: 8px;
        font-style: italic;
    }

    /* 卡片值动画 */
    @keyframes pulse {
        0% {
            transform: scale(1);
        }
        50% {
            transform: scale(1.05);
        }
        100% {
            transform: scale(1);
        }
    }

    .value-updated {
        animation: pulse 0.5s ease;
    }
</style>
<body>
<div id="app" class="app-container">
    <!-- 侧边栏 -->
    <div class="sidebar" :class="{'open': sidebarOpen,'collapsed': sidebarCollapsed}">
        <div class="logo-area">
            <div class="logo-text">数据同步系统</div>
        </div>
        <div class="menu-container">
            <div class="menu-item active" @click="switchMenu(0)">
                <div class="menu-icon">📈</div>
                <div class="menu-text">任务执行统计</div>
            </div>
            <div class="menu-item " @click="switchMenu(1)">
                <div class="menu-icon">📊</div>
                <div class="menu-text">数据同步配置</div>
            </div>
            <div class="menu-item">
                <div class="menu-icon">⏱️</div>
                <div class="menu-text">任务调度</div>
            </div>
            <div class="menu-item">
                <div class="menu-icon">🔧</div>
                <div class="menu-text">系统设置</div>
            </div>
            <div class="menu-item">
                <div class="menu-icon">👤</div>
                <div class="menu-text">用户管理</div>
            </div>
            <div class="menu-item">
                <div class="menu-icon">📚</div>
                <div class="menu-text">操作日志</div>
            </div>
        </div>
    </div>

    <!-- 主内容区 -->
    <div class="main-content">
        <div class="header">
            <div class="toggle-btn" @click="toggleSidebar">☰</div>
            <div class="user-info">
                <span class="user-name">管理员</span>
                <div class="user-avatar">A</div>
            </div>
        </div>

        <!-- 内容区域 -->
        <div class="content-area">
            <!-- 数据同步配置管理 -->
            <div v-show="currentView === 'config'">
                <!-- 全局统计卡片 -->
                <div class="card">
                    <div class="global-stats-title">全局统计概览</div>

                    <div class="stats-cards">
                        <div class="stats-card stats-card-total">
                            <div class="card-icon">📋</div>
                            <div class="card-value" :class="{'value-updated': statsUpdated}">{{ stats.total }}</div>
                            <div class="card-label">总配置数</div>
                        </div>
                        <div class="stats-card stats-card-enabled">
                            <div class="card-icon">✅</div>
                            <div class="card-value" :class="{'value-updated': statsUpdated}">{{ stats.enabled }}</div>
                            <div class="card-label">启用配置</div>
                        </div>
                        <div class="stats-card stats-card-disabled">
                            <div class="card-icon">⛔</div>
                            <div class="card-value" :class="{'value-updated': statsUpdated}">{{ stats.disabled }}</div>
                            <div class="card-label">禁用配置</div>
                        </div>
                        <div class="stats-card stats-card-high">
                            <div class="card-icon">🔥</div>
                            <div class="card-value" :class="{'value-updated': statsUpdated}">{{ stats.highPriority }}
                            </div>
                            <div class="card-label">高优先级</div>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-title">
                        <span>数据同步配置管理</span>
                        <button class="btn btn-primary" @click="openCreateDialog">
                            <i>+</i> 新增配置
                        </button>
                    </div>

                    <!-- 搜索区域 -->
                    <div class="search-area">
                        <div class="search-item">
                            <label class="search-label">源表名称：</label>
                            <input type="text" class="search-input" v-model="search.sourceTable"
                                   placeholder="输入源表名称">
                        </div>
                        <div class="search-item">
                            <label class="search-label">目标表名称：</label>
                            <input type="text" class="search-input" v-model="search.targetTable"
                                   placeholder="输入目标表名称">
                        </div>
                        <div class="search-item">
                            <label class="search-label">状态：</label>
                            <select class="search-select" v-model="search.enabled">
                                <option value="">全部状态</option>
                                <option value="true">启用</option>
                                <option value="false">禁用</option>
                            </select>
                        </div>
                        <button class="btn btn-primary" @click="loadConfigs">搜索</button>
                        <button class="btn btn-info" @click="resetSearch">重置</button>
                    </div>

                    <!-- 表格区域 -->
                    <div class="table-container">
                        <table class="el-table">
                            <thead>
                            <tr>
                                <th>ID</th>
                                <th>源表</th>
                                <th>目标表</th>
                                <th>同步列</th>
                                <th>唯一键</th>
                                <th>调度类型</th>
                                <th>调度值</th>
                                <th>状态</th>
                                <th>优先级</th>
                                <th>最后同步时间</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr v-for="config in configs" :key="config.id">
                                <td>{{ config.id }}</td>
                                <td>{{ config.sourceTable }}</td>
                                <td>{{ config.targetTable }}</td>
                                <td>{{ config.syncColumn }}</td>
                                <td>{{ config.uniqueKey }}</td>
                                <td>
                                    <span v-if="config.scheduleType === 'FIXED'">固定间隔</span>
                                    <span v-else>Cron</span>
                                </td>
                                <td>
                                    <span v-if="config.scheduleType === 'FIXED'">每 {{ config.syncInterval
                                        }} 分钟</span>
                                    <span v-else>{{ config.cronExpression }}</span>
                                </td>
                                <td>
                                    <span v-if="config.enabled" class="status-badge status-enabled">启用</span>
                                    <span v-else class="status-badge status-disabled">禁用</span>
                                </td>
                                <td>
                                    <span v-if="config.priority === '1'" class="status-badge priority-high">高</span>
                                    <span v-else-if="config.priority === '2'"
                                          class="status-badge priority-medium">中</span>
                                    <span v-else class="status-badge priority-low">低</span>
                                </td>
                                <td>{{ config.lastSyncTime || '-' }}</td>
                                <td>
                                    <button v-if="!config.enabled" class="btn btn-success action-btn"
                                            @click="enableConfig(config.id)">启用
                                    </button>
                                    <button v-else class="btn btn-warning action-btn" @click="triggerSync(config.id)">
                                        同步
                                    </button>
                                    <button class="btn btn-primary action-btn" @click="editConfig(config)">编辑</button>
                                    <button class="btn btn-danger action-btn" @click="deleteConfig(config.id)">删除
                                    </button>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                    </div>

                    <!-- 分页 -->
                    <div class="pagination">
                        <button :disabled="pagination.pageNum === 1" @click="changePage(pagination.pageNum - 1)">
                            上一页
                        </button>
                        <button v-for="page in pagination.pages" :key="page"
                                :class="{active: page === pagination.pageNum}"
                                @click="changePage(page)">
                            {{ page }}
                        </button>
                        <button :disabled="pagination.pageNum === pagination.pages"
                                @click="changePage(pagination.pageNum + 1)">下一页
                        </button>
                    </div>
                </div>
            </div>

            <!-- 任务执行统计 -->
            <div v-show="currentView === 'stats'" style="display: none">
                <div class="card">
                    <div class="card-title">任务执行情况统计</div>

                    <!-- 状态卡片 -->
                    <div class="stats-cards">
                        <div class="stats-card stats-card-enabled">
                            <div class="card-icon">✅</div>
                            <div class="card-value">142</div>
                            <div class="card-label">今日成功</div>
                        </div>
                        <div class="stats-card stats-card-disabled">
                            <div class="card-icon">❌</div>
                            <div class="card-value">5</div>
                            <div class="card-label">今日失败</div>
                        </div>
                        <div class="stats-card stats-card-total">
                            <div class="card-icon">📊</div>
                            <div class="card-value">96.6%</div>
                            <div class="card-label">成功率</div>
                        </div>
                        <div class="stats-card stats-card-high">
                            <div class="card-icon">⏱️</div>
                            <div class="card-value">1.2s</div>
                            <div class="card-label">平均耗时</div>
                        </div>
                    </div>

                    <!-- 图表区域 -->
                    <div class="chart-container">
                        <div class="chart-card">
                            <div class="chart-title">任务执行趋势</div>
                            <div class="chart-content" id="trendChart"></div>
                        </div>
                        <div class="chart-card">
                            <div class="chart-title">成功/失败比例</div>
                            <div class="chart-content" id="ratioChart"></div>
                        </div>
                        <div class="chart-card">
                            <div class="chart-title">优先级分布</div>
                            <div class="chart-content" id="priorityChart"></div>
                        </div>
                        <div class="chart-card">
                            <div class="chart-title">执行时间分布</div>
                            <div class="chart-content" id="durationChart"></div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 新增/编辑表单 -->
            <div v-show="currentView === 'form'">
                <div class="card">
                    <div class="card-title">
                        <span>{{ formTitle }}</span>
                    </div>

                    <div class="form-container">
                        <div class="form-row">
                            <div class="form-item">
                                <label class="form-label required">源表名称</label>
                                <input type="text" class="form-input" v-model="formData.sourceTable"
                                       placeholder="请输入源表名称" required>
                            </div>
                            <div class="form-item">
                                <label class="form-label required">目标表名称</label>
                                <input type="text" class="form-input" v-model="formData.targetTable"
                                       placeholder="请输入目标表名称" required>
                            </div>
                        </div>

                        <div class="form-row">
                            <div class="form-item">
                                <label class="form-label required">同步列</label>
                                <input type="text" class="form-input" v-model="formData.syncColumn"
                                       placeholder="用于增量同步的时间戳列" required>
                            </div>
                            <div class="form-item">
                                <label class="form-label required">唯一键</label>
                                <input type="text" class="form-input" v-model="formData.uniqueKey"
                                       placeholder="逗号分隔的列名" required>
                            </div>
                        </div>

                        <div class="form-row">
                            <div class="form-item">
                                <label class="form-label">删除标记列</label>
                                <input type="text" class="form-input" v-model="formData.deleteFlagColumn"
                                       placeholder="标识删除的列（可选）">
                            </div>
                            <div class="form-item">
                                <label class="form-label">执行窗口</label>
                                <input type="text" class="form-input" v-model="formData.executionWindow"
                                       placeholder="例如：00:00-06:00">
                            </div>
                        </div>
                        <!-- 修改同步间隔的输入框，根据调度类型动态显示 -->
                        <div class="form-row">
                            <div class="form-item">
                                <label class="form-label required">调度类型</label>
                                <div class="form-radio-group">
                                    <label class="form-radio">
                                        <input type="radio" name="scheduleType" value="FIXED"
                                               v-model="formData.scheduleType"> 固定间隔
                                    </label>
                                    <label class="form-radio">
                                        <input type="radio" name="scheduleType" value="CRON"
                                               v-model="formData.scheduleType"> Cron表达式
                                    </label>
                                </div>
                            </div>
                            <div class="form-item" v-if="formData.scheduleType === 'FIXED'">
                                <label class="form-label required">同步间隔(分钟)</label>
                                <input type="number" class="form-input" v-model="formData.syncInterval" min="1"
                                       required>
                            </div>

                            <div class="form-item" v-if="formData.scheduleType === 'CRON'">
                                <label class="form-label required">Cron表达式</label>
                                <input type="text" class="form-input" v-model="formData.cronExpression"
                                       placeholder="例如：0 0/5 * * * ?" required>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-item">
                                <label class="form-label required">状态</label>
                                <div class="form-radio-group">
                                    <label class="form-radio">
                                        <input type="radio" name="status" value="true" v-model="formData.enabled"> 启用
                                    </label>
                                    <label class="form-radio">
                                        <input type="radio" name="status" value="false" v-model="formData.enabled"> 禁用
                                    </label>
                                </div>
                            </div>
                        </div>
                        <div class="form-actions">
                            <button class="cancel-btn" @click="closeForm">取消</button>
                            <button class="submit-btn" @click="saveConfig">保存配置</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 移动端遮罩层 -->
    <div class="overlay" v-show="overlayVisible" @click="closeSidebar"></div>

    <!-- 通知组件 -->
    <div v-if="notification.show" class="notification" :class="notification.type">
        <div class="notification-icon">
            <span v-if="notification.type === 'success'">✓</span>
            <span v-else-if="notification.type === 'error'">✗</span>
            <span v-else>!</span>
        </div>
        <div class="notification-content">
            <div class="notification-title">{{ notification.title }}</div>
            <div class="notification-message">{{ notification.message }}</div>
        </div>
    </div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            sidebarCollapsed: false,
            overlayVisible: false,
            sidebarOpen: false,
            currentView: 'stats',
            configs: [],
            formData: {
                id: null,
                sourceTable: '',
                targetTable: '',
                syncColumn: '',
                uniqueKey: '',
                deleteFlagColumn: '',
                executionWindow: 'ALL',
                priority: '3',
                enabled: true,
                scheduleType: 'FIXED', // 默认固定间隔
                syncInterval: 5,       // 固定间隔的分钟数
                cronExpression: '',    // 新增Cron表达式字段
            },
            formTitle: '新增同步配置',
            search: {
                sourceTable: '',
                targetTable: '',
                enabled: ''
            },
            pagination: {
                pageNum: 1,
                pageSize: 10,
                total: 0,
                pages: 1
            },
            stats: {
                total: 0,
                enabled: 0,
                disabled: 0,
                highPriority: 0
            },
            statsUpdated: false,
            notification: {
                show: false,
                type: 'success',
                title: '',
                message: '',
                timer: null
            }
        },
        mounted() {
            this.loadConfigs();
            this.countConfigStatus();
            this.$nextTick(() => {
                this.initCharts();
            });
        },
        methods: {
            // 切换菜单
            switchMenu(index) {
                document.querySelectorAll('.menu-item').forEach(item => item.classList.remove('active'));
                document.querySelectorAll('.menu-item')[index].classList.add('active');

                if (index === 0) {
                    this.currentView = 'stats';
                    this.$nextTick(() => {
                        this.initCharts();
                    });
                } else if (index === 1) {
                    this.currentView = 'config';
                }
            },

            // 加载配置数据
            loadConfigs() {
                const params = {
                    pageNum: this.pagination.pageNum,
                    pageSize: this.pagination.pageSize,
                    ...this.search
                };

                axios.post('/api/sync-config/page', params)
                    .then(response => {
                        this.configs = response.data.list;
                        this.pagination.total = response.data.total;
                        this.pagination.pages = response.data.pages;
                    })
                    .catch(error => {
                        this.showNotification('error', '加载失败', '无法加载配置数据');
                    });
            },

            // 切换分页
            changePage(page) {
                if (page < 1 || page > this.pagination.pages) return;
                this.pagination.pageNum = page;
                this.loadConfigs();
            },

            // 重置搜索
            resetSearch() {
                this.search = {
                    sourceTable: '',
                    targetTable: '',
                    enabled: ''
                };
                this.pagination.pageNum = 1;
                this.loadConfigs();
            },

            // 打开创建对话框
            openCreateDialog() {
                this.formData = {
                    id: null,
                    sourceTable: '',
                    targetTable: '',
                    syncColumn: '',
                    uniqueKey: '',
                    deleteFlagColumn: '',
                    syncInterval: 5,
                    executionWindow: 'ALL',
                    priority: '3',
                    enabled: true
                };
                this.formTitle = '新增同步配置';
                this.currentView = 'form';
            },

            // 编辑配置
            editConfig(config) {
                // 确保scheduleType和cronExpression有值
                this.formData = {
                    ...config,
                    scheduleType: config.scheduleType || 'FIXED',
                    cronExpression: config.cronExpression || ''
                };
                this.formTitle = '编辑同步配置 #' + config.id;
                this.currentView = 'form';
            },

            // 关闭表单
            closeForm() {
                this.currentView = 'config';
            },

            // 保存配置
            saveConfig() {
                const method = this.formData.id ? 'update' : 'create';

                axios.post(`/api/sync-config/${method}`, this.formData)
                    .then(() => {
                        this.showNotification('success', '保存成功', '配置已保存');
                        this.closeForm();
                        this.loadConfigs();
                        // 更新全局统计
                        this.countConfigStatus();
                    })
                    .catch(error => {
                        this.showNotification('error', '保存失败', error.response?.data || '保存配置时出错');
                    });
            },

            // 启用配置
            enableConfig(id) {
                axios.post(`/api/sync-config/update-status?id=${id}&enabled=true`)
                    .then(() => {
                        this.showNotification('success', '启用成功', '配置已启用');
                        this.loadConfigs();
                        // 更新全局统计
                        this.countConfigStatus();
                    })
                    .catch(error => {
                        this.showNotification('error', '启用失败', error.response?.data || '启用配置时出错');
                    });
            },

            // 触发同步
            triggerSync(id) {
                axios.post(`/api/sync-config/trigger?id=${id}`)
                    .then(() => {
                        this.showNotification('success', '同步触发', '同步任务已开始执行');
                        this.loadConfigs();
                    })
                    .catch(error => {
                        this.showNotification('error', '同步失败', error.response?.data || '触发同步时出错');
                    });
            },

            // 删除配置
            deleteConfig(id) {
                if (!confirm('确定要删除配置 #' + id + ' 吗？此操作不可恢复！')) return;

                axios.post(`/api/sync-config/delete?id=${id}`)
                    .then(() => {
                        this.showNotification('success', '删除成功', '配置已删除');
                        this.loadConfigs();
                        // 更新全局统计
                        this.countConfigStatus();
                    })
                    .catch(error => {
                        this.showNotification('error', '删除失败', error.response?.data || '删除配置时出错');
                    });
            },

            // 初始化图表
            initCharts() {
                // 任务执行趋势图
                const trendChart = echarts.init(document.getElementById('trendChart'));
                trendChart.setOption({
                    tooltip: {trigger: 'axis'},
                    legend: {data: ['成功次数', '失败次数'], bottom: 0},
                    grid: {left: '3%', right: '4%', bottom: '40px', top: '10px'},
                    xAxis: {type: 'category', data: ['10/10', '10/11', '10/12', '10/13', '10/14', '10/15', '10/16']},
                    yAxis: {type: 'value'},
                    series: [
                        {
                            name: '成功次数', type: 'line', smooth: true, data: [120, 132, 101, 134, 90, 230, 210],
                            lineStyle: {color: '#67C23A', width: 3},
                            areaStyle: {color: 'rgba(103, 194, 58, 0.3)'}
                        },
                        {
                            name: '失败次数', type: 'line', smooth: true, data: [3, 5, 2, 6, 1, 4, 2],
                            lineStyle: {color: '#F56C6C', width: 3}
                        }
                    ]
                });

                // 成功/失败比例图
                const ratioChart = echarts.init(document.getElementById('ratioChart'));
                ratioChart.setOption({
                    tooltip: {trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)'},
                    legend: {orient: 'horizontal', bottom: 0, data: ['成功', '失败']},
                    series: [{
                        name: '任务执行结果', type: 'pie', radius: ['40%', '70%'], center: ['50%', '45%'],
                        itemStyle: {borderRadius: 10, borderColor: '#fff', borderWidth: 2},
                        label: {show: true, formatter: '{b}: {d}%'},
                        data: [
                            {value: 142, name: '成功', itemStyle: {color: '#67C23A'}},
                            {value: 5, name: '失败', itemStyle: {color: '#F56C6C'}}
                        ]
                    }]
                });

                // 优先级分布图
                const priorityChart = echarts.init(document.getElementById('priorityChart'));
                priorityChart.setOption({
                    tooltip: {trigger: 'axis'},
                    grid: {left: '3%', right: '4%', bottom: '3%', top: '10px'},
                    xAxis: {type: 'value'},
                    yAxis: {type: 'category', data: ['低', '中', '高']},
                    series: [{
                        name: '任务数量', type: 'bar', data: [35, 42, 23],
                        itemStyle: {color: (params) => ['#67C23A', '#E6A23C', '#F56C6C'][params.dataIndex]},
                        label: {show: true, position: 'right'}
                    }]
                });

                // 执行时间分布图
                const durationChart = echarts.init(document.getElementById('durationChart'));
                durationChart.setOption({
                    tooltip: {trigger: 'axis', formatter: '{b}<br/>任务数: {c}'},
                    grid: {left: '3%', right: '4%', bottom: '3%', top: '10px'},
                    xAxis: {type: 'category', data: ['<0.5s', '0.5-1s', '1-2s', '2-5s', '>5s']},
                    yAxis: {type: 'value'},
                    series: [{
                        data: [45, 78, 62, 30, 12], type: 'bar',
                        itemStyle: {color: '#409EFF'},
                        label: {show: true, position: 'top'}
                    }]
                });

                // 响应窗口大小变化
                window.addEventListener('resize', () => {
                    trendChart.resize();
                    ratioChart.resize();
                    priorityChart.resize();
                    durationChart.resize();
                });
            },

            // 显示通知
            showNotification(type, title, message) {
                this.notification = {
                    show: true,
                    type,
                    title,
                    message
                };

                // 自动关闭通知
                clearTimeout(this.notification.timer);
                this.notification.timer = setTimeout(() => {
                    this.notification.show = false;
                }, 3000);
            },

            // 切换侧边栏
            toggleSidebar() {
                if (window.innerWidth < 993) {
                    // 移动端逻辑
                    this.sidebarOpen = !this.sidebarOpen;
                    this.overlayVisible = this.sidebarOpen;
                } else {
                    // PC 端逻辑 - 切换折叠状态
                    this.sidebarCollapsed = !this.sidebarCollapsed;
                }
            },

            // 关闭侧边栏（移动端）
            closeSidebar() {
                if (window.innerWidth < 993) {
                    // 移动端逻辑
                    this.sidebarOpen = false;
                    this.overlayVisible = false;
                } else {
                    // PC 端逻辑 - 收起侧边栏
                    this.sidebarCollapsed = true;
                }
            },
            countConfigStatus() {
                axios.get(`/api/sync-statistics/countConfigStatus`)
                    .then(response => {
                        // 标记数据更新状态用于动画
                        this.statsUpdated = true;

                        // 设置数据
                        this.stats.total = response.data.total;
                        this.stats.enabled = response.data.enabled;
                        this.stats.disabled = response.data.disabled;
                        this.stats.highPriority = response.data.highPriority;

                        // 重置动画状态
                        setTimeout(() => {
                            this.statsUpdated = false;
                        }, 500);
                    })
                    .catch(error => {
                        this.showNotification('error', '统计配置状态时出错', '统计配置状态时出错');
                    });
            }
        },

    });
</script>
</body>
</html>
